<?php
// +----------------------------------------------------------------------
// 文件及文件夹处理类
// +----------------------------------------------------------------------
namespace util;
//文件处理类
class File {
    /**
     * 创建目录
     * @param $dir  目录名
     * @return boolean true 成功， false 失败
     */
    static public function mk_dir($dir) {
        $dir = rtrim($dir,'/').'/';
        if(!is_dir($dir))
        {
            if(mkdir($dir, 0700, true)==false)
            {
                return false;
            }
            return true;
        }
        return true;
    }

    /**
     * 基于数组创建目录和文件
     * @param array $files 文件名数组
     */
    static public function create_dir_or_files($files) {
        foreach ($files as $key => $value) {
            if(substr($value, -1) == '/'){
                mkdir($value, 0777, true);
            }else{
                @file_put_contents($value, '');
            }
        }
    }

    /**
     * 读取文件内容
     * @param $filename  文件名
     * @return string 文件内容
     */
    static public function read_file($filename) {
        $content = '';
        if(function_exists('file_get_contents'))
        {
            @$content = file_get_contents($filename);
        }
        else
        {
            if(@$fp = fopen($filename, 'r'))
            {
                @$content = fread($fp, filesize($filename));
                @fclose($fp);
            }
        }
        return $content;
    }

    /**
     * 写文件
     * @param $filename  文件名
     * @param $writetext 文件内容
     * @param $openmod     打开方式
     * @return boolean true 成功, false 失败
     */
    static function write_file($filename, $writetext, $openmod='w') {
        if(@$fp = fopen($filename, $openmod))
        {
            flock($fp, 2);
            fwrite($fp, $writetext);
            fclose($fp);
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * 删除目录
     * @param $dirName      原目录
     * @return boolean true 成功, false 失败
     */
    static function del_dir($dirName) {
        if (!file_exists($dirName))
        {
            return false;
        }

        $dir = opendir($dirName);
        while ($fileName = readdir($dir))
        {
            $file = $dirName . '/' . $fileName;
            if ($fileName != '.' && $fileName != '..')
            {
                if (is_dir($file))
                {
                    self::del_dir($file);
                }
                else
                {
                    unlink($file);
                }
            }
        }
        closedir($dir);
        return rmdir($dirName);
    }

    /**
     * 复制目录
     * @param $surDir      原目录
     * @param $toDir      目标目录
     * @return boolean true 成功, false 失败
     */
    static function copy_dir($surDir,$toDir) {
        $surDir = rtrim($surDir,'/').'/';
        $toDir = rtrim($toDir,'/').'/';
        if (!file_exists($surDir))
        {
            return  false;
        }

        if (!file_exists($toDir))
        {
            self::mk_dir($toDir);
        }
        $file = opendir($surDir);
        while ($fileName = readdir($file))
        {
            $file1 = $surDir .'/'.$fileName;
            $file2 = $toDir .'/'.$fileName;
            if ($fileName != '.' && $fileName != '..')
            {
                if (is_dir($file1))
                {
                    self::copy_dir($file1, $file2);
                }
                else
                {
                    copy($file1, $file2);
                }
            }
        }
        closedir($file);
        return true;
    }

    /**
     * 列出目录
     * @param $dir  目录名
     * @return 目录数组。列出文件夹下内容，返回数组 $dirArray['dir']:存文件夹；$dirArray['file']：存文件
     */
    static function get_dirs($dir) {
        $dir = rtrim($dir,'/').'/';
        $dirArray = [];
        if (false != ($handle = opendir ( $dir )))
        {
            $i = 0;
            $j = 0;
            while ( false !== ($file = readdir ( $handle )) )
            {
                if (is_dir ( $dir . $file ))
                { //判断是否文件夹
                    $dirArray ['dir'] [$i] = $file;
                    $i ++;
                }
                else
                {
                    $dirArray ['file'] [$j] = $file;
                    $j ++;
                }
            }
            closedir ($handle);
        }
        return $dirArray;
    }

    /**
     * 统计文件夹大小
     * @param $dir  目录名
     * @return int 文件夹大小(单位 B)
     */
    static function get_size($dir) {
        $dirlist = opendir($dir);
        $dirsize = 0;
        while (false !==  ($folderorfile = readdir($dirlist)))
        {
            if($folderorfile != "." && $folderorfile != "..")
            {
                if (is_dir("$dir/$folderorfile"))
                {
                    $dirsize += self::get_size("$dir/$folderorfile");
                }
                else
                {
                    $dirsize += filesize("$dir/$folderorfile");
                }
            }
        }
        closedir($dirlist);
        return $dirsize;
    }

    /**
     * 检测是否为空文件夹
     * @param $dir  目录名
     * @return boolean true 空， fasle 不为空
     */
    static function empty_dir($dir) {
        return (($files = @scandir($dir)) && count($files) <= 2);
    }

    //$dirpath 目标路径
    static function check_owner($dirpath, $owner = 'www', $mod='0777'){ //(创建)验证设置文件夹所有者
        self::create_folders($dirpath,$mod);
        $stat = stat($dirpath);
        if (isset($stat['uid']) && $pwuid = posix_getpwuid($stat['uid'])) {//posix_getpwuid函数用于根据用户ID获取用户信息‌
            if (isset($pwuid['name']) && $pwuid['name'] != $owner) { //不为$owner则修改所有者
                if(is_writable($dirpath)){
                    $shell = 'chown  ' . $owner . ' ' . $dirpath . '  -R;'; //降权为www所有者(-R 处理指定目录以及其子目录下的所有文件)
                    $shell .= "chmod  $mod " . $dirpath . '  -R 2>&1'; //变更文件夹权限设置(输出错误信息到标准错误输出流2>&1)
                    shell_exec($shell);
                }else{
                    if((session('user_auth.role') ?? '')==1){//admin账号，抛出异常
                        $username = trim(shell_exec('whoami'));
                        throw new \Exception("当前用户: " . $username.",路径：" . $dirpath . '权限不足');
                    }
                }
                
            }
        }
    }

    static function create_folders($dir,$mod='777'){ //递归创建多级目录
        return is_dir($dir) or (self::create_folders(dirname($dir),$mod) and mkdir($dir) and chmod($dir, octdec($mod)) and chown($dir, 'www')); //不要直接使用mkdir函数指定权限，以避免系统umask的影响
    }

    static function create_file($folder_name, $full_path){ //递归创建多级目录
        self::check_owner($folder_name); //(创建)验证设置文件夹所有者    
        if (!file_exists($full_path)) {
            $myfile = fopen($full_path, "w"); //创建文件
            fclose($myfile);
        }
    }

    static function get_ext($contentType){ //要根据Content-Type判断返回的扩展名
        $mimeTypes = [
            'image/jpeg' => 'jpg',
            'image/png' => 'png',
            'image/gif' => 'gif',
            'image/bmp' => 'bmp',
            'image/webp' => 'webp',
            'image/svg+xml' => 'svg',
            'application/pdf' => 'pdf',
            'application/zip' => 'zip',
            // 添加其他常见的Content-Type和对应的扩展名
        ];

        if (isset($mimeTypes[$contentType])) {
            return $mimeTypes[$contentType];
        } else {
            return ''; // 未知的Content-Type
        }
    }
}
